#ifndef _AIR_PARTICLE_
#define _AIR_PARTICLE_


#include "cocos2d.h"

#include "Tools.h"

#include "vector"

#include <set>

#include <map>

#include <queue>

#include <list>

#define QUAD_DEPTH 5

using namespace cocos2d;
using namespace std;

class QuadNode;
class Air;
class Fire;



class Road{
public:
	Point start,end;
	list<Point> road;
	int stop_to_release;
};

class quadRect{
public:
	bool isStar;
	QuadNode* target;
    float top,bottom,left,right;
	static quadRect* createWithSprite(Sprite* sprite);
};

class QuadNode{
public:
	set<quadRect*> objs;
	int depth;
    quadRect rect;
	int order[4];
    QuadNode *list[4];
    QuadNode *parent;
};



class AirParticle:public Sprite{
public:
    static AirParticle* create(Air* air,Texture2D* texture,Point speed, float changeSize,float life,float startOpacity,float endOpacity);
	void checkSchedule();
	void updateAir(float dt);
    float _speed,changeSize,life,_startOpacity, startOpacity,_endOpacity; 
	quadRect* _rect;
	Air* _air;
};

class Fire:public Node{
public:
	bool init(Sprite* sprite,Air* air);
	void update(float dt)override;
	static Fire* create(Sprite* sprite,Air* air);
private:
	Sprite* _sprite;
	quadRect* _rect;
	Air* _air;
};

class Air:public Node
{
public:

	void generateTree();

	inline bool containsBox(quadRect* rect,QuadNode* node){


		//log("node: depth = %d top:%lf,left:%lf,right:%lf,bottom:%lf",node->depth,node->rect.top,node->rect.left,node->rect.right,node->rect.bottom);

		//log("rect:%x  rectTop:%lf,rectbottom:%lf,rectLeft:%lf,rectRight:%lf",rect,rect->top,rect->bottom,rect->left,rect->right);


	return rect->right < node->rect.right&&
			rect->top < node->rect.top&&
			rect->left > node->rect.left&&
			rect->bottom > node->rect.bottom;
	};


	void insert(quadRect* rect);

	void insertObject(quadRect* rect);

	void insert(quadRect *rect,QuadNode* Croot); 
	
	void updateAir(float dt);

	void change(quadRect* rect);

	void checkOut(QuadNode* node){};

    bool init();

    void updateParticle();


    inline void setEmissionRate(float rate){_rate = rate;}

    inline void setSpeed(float speed){_speed = speed;}

    inline void setSpeedVar(float speedVar){_speedVar = speedVar;}

    inline void setChangeSize(float size){_size = size;}

	inline void setChangeSizeVar(float sizeVar){_sizeVar = sizeVar;}

    void checkCrash(Sprite* sprite){};

    void setTouchLayer(Layer* layer);

    inline void setLife(float life){_life = life;} 

	inline void setLifevar(float lifeVar){_lifeVar = lifeVar;}

    CREATE_FUNC(Air);

private:

	void releaseAir(float dt);

    void fill(Point &start,Point &end,Road* road);

    void addParticle(Point pos,float lenght);

private:

	EventListenerTouchAllAtOnce* listenner;

	queue<QuadNode*> Qqueue;

	set<Sprite*> particles;

	QuadNode* root;

    queue<AirParticle*> airQuene;
	
    float _interval;

    float _rate;

    float _speed;

    float _speedVar;

    float _size;

	float _sizeVar;
    
    Layer* _layer;

    float _life;

	float _lifeVar;

	float _startOpacity,_endOpacity;

	float _posVar;

	float _maxInterval;
	
	std::map<int,Road*> roadMap;
};

#endif
